package com.atguigu.demojuc.chap03;

/**
 * @author njg
 * @version 1.0
 * @date 2025/6/17 17:16
 */

/**
 * 上
 *      高内聚 低耦合
 *      线程 操作 资源类
 *
 * 多线程编程模板（中）：**
 *
 * 1. 判断
 * 2. 干活
 * 3. 通知
 *
 **下
 * 用while代替if   防止虚假唤醒
 *
 * 线程间通信模型：**
 *
 * 1. 生产者+消费者
 * 2. 通知等待唤醒机制
 */
//两个线程操作一个初始值为0的变量，实现一个线程对变量增加1，一个线程对变量减少1，交替10轮。

class ShareDataOne {
    private Integer number = 0;

    public synchronized void increment() throws InterruptedException {
        while (number != 0){
            wait();
        }
        System.out.println(Thread.currentThread().getName() + "\t" + "对"+(number++)+"加一，number="+number);
        notifyAll();
    }
    public synchronized void decrement() throws InterruptedException {
        while (number != 1){
            wait();
        }
        System.out.println(Thread.currentThread().getName() + "\t" + "对"+(number--)+"减一，number="+number);
        notifyAll();
    }
}

public class NotifyWaitDemo{
    public static void main(String[] args) {
        ShareDataOne shareDataOne = new ShareDataOne();
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                try {
                    shareDataOne.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "A").start();
        }
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                try {
                    shareDataOne.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "B").start();
        }
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                try {
                    shareDataOne.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "C").start();
        }
        for (int i = 1; i <= 10; i++) {
            new Thread(() -> {
                try {
                    shareDataOne.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "D").start();
        }
    }
}
